﻿using AiShow.Common;
using AiShow.DAL;
using AiShow.IBLL;
using AiShow.IDAL;
using AiShow.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AiShow.BLL
{
    /// <summary>
    /// 社交业务管理接口
    /// </summary>
    public class FriendManager : IFriendManager
    {
        private const string friendKeyPrefix = "Friend";
        private const string messageKeyPrefix = "Message";

        /// <summary>
        /// 获取好友列表
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <returns></returns>
        public Dictionary<int, Friend> GetFriends(int selfId)
        {
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Dictionary<string, Friend> friendDictionary = RedisHelper.HashGetAll<Friend>(selfKey);
            return friendDictionary.ToDictionary(m => int.Parse(m.Key), m => m.Value);
        }

        /// <summary>
        /// 获取好友信息
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <returns></returns>
        public Friend GetFriend(int selfId, int otherId)
        {
            // 获取聊天Id
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = RedisHelper.HashGet<Friend>(selfKey, otherId.ToString());
            // 返回结果
            return selfFriend;
        }

        /// <summary>
        /// 是否是好友
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <returns></returns>
        public bool IsFriend(int selfId, int otherId)
        {
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            return RedisHelper.HashExists(selfKey, otherId.ToString());
        }

        /// <summary>
        /// 添加好友
        /// </summary>
        /// <param name="selfId"></param>
        /// <param name="otherId"></param>
        /// <returns></returns>
        public bool AddFriend(int selfId, int otherId)
        {
            // 查询用户信息
            IUserService userService = new UserService();
            TBUsers self = userService.FindByUserId(selfId);
            TBUsers other = userService.FindByUserId(otherId);
            if (self == null || other == null)
                return false;
            // 聊天Id
            string chatId = Guid.NewGuid().ToString("N");
            // 添加对方到我的好友
            DateTime timeNow = DateTime.Now;
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = new Friend()
            {
                NickName = other.NickName,
                Avatar = other.Avatar,
                LastMessage = new Message()
                {
                    UserId = other.Id,
                    Content = other.NickName,
                    AddTime = timeNow
                },
                ChatId = chatId
            };
            bool selfResult = RedisHelper.HashSet(selfKey, otherId.ToString(), selfFriend);
            // 添加我到对方的好友
            string otherKey = $"{friendKeyPrefix}_{otherId}";
            Friend otherFriend = new Friend()
            {
                NickName = self.NickName,
                Avatar = self.Avatar,
                LastMessage = new Message()
                {
                    UserId = self.Id,
                    Content = self.NickName,
                    AddTime = timeNow
                },
                ChatId = chatId
            };
            bool otherResult = RedisHelper.HashSet(otherKey, selfId.ToString(), otherFriend);
            // 返回结果
            return selfResult && otherResult;
        }

        /// <summary>
        /// 获取消息记录
        /// </summary>
        /// <param name="selfId"></param>
        /// <param name="otherId"></param>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<Message> GetMessages(int selfId, int otherId, int pageNumber, int pageSize = 10)
        {
            // 获取聊天Id
            Friend selfFriend = GetFriend(selfId, otherId);
            string chatId = selfFriend.ChatId;
            // 读取消息记录
            string messageKey = $"{messageKeyPrefix}_{chatId}";
            int start = (pageNumber - 1) * pageSize;
            int stop = start + pageSize - 1;
            List<Message> messageList = RedisHelper.SortedSetRangeByRank<Message>(messageKey, start, stop, false);
            // 返回结果
            return messageList;
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <param name="content">消息内容</param>
        /// <returns></returns>
        public bool SendMessage(int selfId, int otherId, string content)
        {
            DateTime timeNow = DateTime.Now;
            // 获取聊天Id
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = RedisHelper.HashGet<Friend>(selfKey, otherId.ToString());
            string chatId = selfFriend.ChatId;
            // 存储消息到消息列表
            string messageKey = $"{messageKeyPrefix}_{chatId}";
            Message message = new Message()
            {
                UserId = selfId,
                Content = content,
                AddTime = timeNow
            };
            long score = TimeHelper.ConvertDateTimeByUnix(DateTime.Now);
            bool messageResult = RedisHelper.SortedSetAdd(messageKey, message, score);
            // 更新最后消息到我的好友列表
            selfFriend.LastMessage = message;
            bool selfResult = RedisHelper.HashSet(selfKey, otherId.ToString(), selfFriend);
            // 更新最后消息到对方的好友列表
            string otherKey = $"{friendKeyPrefix}_{otherId}";
            Friend otherFriend = RedisHelper.HashGet<Friend>(otherKey, selfId.ToString());
            otherFriend.LastMessage = message;
            bool otherResult = RedisHelper.HashSet(otherKey, selfId.ToString(), otherFriend);
            // 返回结果
            return messageResult && selfResult && otherResult;
        }
    }
}